Des-file format
des-file format is the language which is used to describe the special levels for NetHack. It is compiled into a binary file by lev_comp. It is not a real programming language: there is no flow control, and the order in which different NetHack features are created is fixed. There are two types of levels you can create: mazes and rooms. For MAZE-type levels you "draw" one or more maps with ASCII characters and then describe the monsters, objects and so on that are in the map. For ROOM-type levels, you describe rooms and their contents. The maze-levels are easier to make and understand, and room-type levels do not offer as much control over the level. lev_comp will create a .lev-file for each MAZE and LEVEL definition in the file. These .lev-files will be loaded into NetHack to make the special levels. The .lev-files NetHack loads are actually defined in dungeon.def. Language syntax All lines beginning with # are comments and are ignored by the level compiler, except between MAP and ENDMAP. Example: # This is a comment. MAZE-type levels Maze-type levels begin with MAZE, followed with optional FLAGS, optional INIT_MAP, 0 or more MESSAGEs and up to 9 maze-parts, each of which consists either of NOMAP or GEOMETRY and MAP, followed by zero or more the random register initializers, one of each (RANDOM_MONSTERS, RANDOM_OBJECTS, RANDOM_PLACES), followed by zero or more of the map details (everything else, eg. MONSTER, OBJECT, TRAP, etc.) That is: *MAZE *FLAGS, optional *INIT_MAP, optional *MESSAGE, 0 or more *up to 9 map-parts, which consist of: **NOMAP or GEOMETRY and MAP **RANDOM_MONSTERS, optional **RANDOM_OBJECTS, optional **RANDOM_PLACES, optional **The rest of the definitions of this map-part Example: MAZE:"test",' ' FLAGS:noteleport MESSAGE:"Welcome!" GEOMETRY:center,center MAP ..... .L.L. ..... .L.L. ..... ENDMAP MONSTER:random,random,random OBJECT:'%',random,random MAZE MAZE:"foo",'X' *foo is the unique file name which will be used for this special level, up to 8 characters. For example: soko3-2. This file name which NetHack loads is defined by the way this level is defined in dungeon.def. *'X' is the fill map character. The map will be filled with this dungeon feature before anything else is done. This can also be random, which fills the whole level with a checkerboard grid of walls and stone, so you can use MAZEWALK on it. Example: MAZE:"soko3-2",' ' FLAGS FLAGS:flaglist flaglist is one or more of the following flags, separated by commas *noteleport: Player cannot teleport within the level. *hardfloor: The floor is too hard to dig. *nommap: magic mapping does not work. *arboreal: supposedly an outdoor map. Solid walls and secret corridors will be shown as trees, digging makes floor instead of corridor and randomly created corridors are made out of floor instead of corridor. *shortsighted: Monsters cannot see you from far away. Example: FLAGS:noteleport,hardfloor INIT_MAP INIT_MAP:'X', 'Y', smoothed, joined, lighted, walled This causes the level map to be initialized with a random map generator, similar to how the random Gnomish Mines look like. Each MAZE-level can contain only 0 or 1 of these definitions. *'X' is the "foreground" fill map character. This should be something the player can walk on, as the walkable part will be made out of this. *'Y' is the "background" fill map character. This will surround the foreground area, so can be solid or harmful to player. *smoothed is either true or false, and denotes whether the level will be "smoothed". This means that any foreground character surrounded by fewer than 3 foreground characters is changed to background character. *joined is either true or false, and denotes whether the level will be "joined", so that all parts are accessible by walking. *lighted is either lit, unlit, or random *walled is either true or false. This is equivalent of using a WALLIFY -command. Examples: INIT_MAP: 'L', '.', false, false, unlit, false INIT_MAP: '.', ' ', true, true, random, true MESSAGE MESSAGE:"string" You can have 0 or more of these per special level. Each message line gets separated with a --more-- -prompt in the game. "string" is any message you want player to see when entering the level. Example: MESSAGE: "Well done, mortal!" NOMAP NOMAP Instead of GEOMETRY and MAP, you use this if you think that INIT_MAP creates a good enough random map and you don't want to use any fixed map-parts. See also MAP GEOMETRY GEOMETRY:xadj,yadj This must be followed by a MAP definition, and tells the approximate position of the following MAP-part on the level. *xadj is one of left, half-left, center, half-right, right or random *yadj is one of top, center, bottom or random Example: GEOMETRY:left,top MAP MAP ... ... ... ENDMAP This must be preceded by GEOMETRY definition. You define a map-part by "drawing" with map characters between the MAP and ENDMAP. The map can be up to 21 lines high and each line can be up to 76 chars long. Each line must also be the same length. You can also use numbers inside the map, but those will be ignored; they're considered as line numbers. See also NOMAP. NON_DIGGABLE NON_DIGGABLE:region Sets the walls inside the region as non-diggable. Example: NON_DIGGABLE:(00,00,13,12) NON_PASSWALL NON_PASSWALL:region Players and monsters cannot phase through the walls inside the region Example: NON_PASSWALL:(00,00,13,12) RANDOM_PLACES RANDOM_PLACES:place,... With this command you can set up to 10 coordinate registers, which you can access by using placeN instead of a coordinate in any other command. The registers are shuffled at level creation time. Example: RANDOM_PLACES:(23,9),(37,14),(51,9) OBJECT:'?',"genocide",place0 RANDOM_MONSTERS RANDOM_MONSTERS:'X',... With this command you can set up 10 monster symbol registers, which you can access by using monsterN instead of a monster symbol in any other command. The registers are shuffled at level creation time. Example: RANDOM_MONSTERS: 'E', 'X' MONSTER:monster0,random,(27,05) RANDOM_OBJECTS RANDOM_OBJECTS:'X',... With this command you can set up 10 object class symbol registers, which you can access by using objectN instead of a object class symbol in any other command. The registers are shuffled at level creation time. Example: RANDOM_OBJECTS:'OBJECT:object[0,random,(39,05) DOOR DOOR:state,place Puts a door on the map. *state is one of the following: nodoor, locked, closed, open or random *place is either a coordinate, a RANDOM_PLACES place, or random Example: DOOR:locked,(10,5) DRAWBRIDGE DRAWBRIDGE:place,dir,state *place is either a coordinate, a RANDOM_PLACES place, or random *dir is one of the following: north, east, south or west *state is one of the following: nodoor, locked, closed, open or random Note that the drawbridge placement is different from door placement; the coordinate must be a place where the drawbridge would be when it's open, and from that place towards the direction there should be a wall, where the portcullis will be. Example: DRAWBRIDGE:(25,18), north, closed REGION REGION:(x1,y1,x2,y2), lighted, "type" Define a region on the map with certain light-state and type. *lighted is one of lit, unlit or random. *"type" is one of the room types. You can add filled or unfilled, it will denote whether the room will get stocked with the normal monsters or objects it would get. After that you can add true or false to denote whether the room is irregularly shaped. If the room is irregular, only the first coordinate (x1,y1) must be inside the room, and the room must be closed off from other areas with non-floor map characters. Use the boundary symbol 'B' in the MAP to enclose an irregular room; it will be converted to floor symbol '.' after the level has been created. Examples: REGION:(43,12,49,16),unlit,"ordinary" REGION:(12,01,20,09),unlit,"morgue",unfilled REGION:(11,03,29,10),lit,"temple",filled,true STAIR-region STAIR:(x1,y1,x2,y2), (x3,y3,x4,y4), updown Places a stair within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). *updown is either up or down, denoting the direction of the stairs. If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP. Example: STAIR:(0,0,79,20), (20,5,50,15), up STAIR:levregion(01,0,79,20), (0,0,28,12), up STAIR:(0,0,50,10), levregion(10,0,20,15), down PORTAL PORTAL:(x1,y1,x2,y2), (x3,y3,x4,y4),"levelname" Places a magical portal within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). The portal will level teleport player to the level with the name "levelname". If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP. Example: PORTAL:levregion(57,01,78,19),(0,0,0,0),"fire" PORTAL:(0,0,75,19),(65,13,75,19),"air" TELEPORT_REGION TELEPORT_REGION:(x1,y1,x2,y2),(x3,y3,x4,y4) Restricts the area where player can end up on the level when he level teleports or falls in there. Player will end up within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP. You can also add an optional direction parameter, either up or down, which will tell when this rule is applied; when player is coming from below or above. Example: TELEPORT_REGION:(69,16,69,16),(0,0,0,0) TELEPORT_REGION:levregion(56,00,79,20),levregion(01,00,55,20),down BRANCH BRANCH:(x1,y1,x2,y2),(x3,y3,x4,y4) Places stairs or a magical portal to a dungeon branch within an area covered by (x1,y1,x2,y2) and not covered by (x3,y3,x4,y4). If the area is prefixed with levregion then the coordinates are relative to the whole level, otherwise the coordinates are relative to the last-defined MAP. Example: BRANCH:levregion(51,2,77,18),(0,0,40,20) MAZEWALK MAZEWALK:place,dir Creates a random maze, starting from place. *place is either a coordinate, a RANDOM_PLACES place, or random *dir is one of the following: north, east, south or west Mazewalk turns map grids with solid stone (' ') into floor ('.'). From the starting position, it checks the mapgrid in the direction given, and if it's solid stone, it will move there, and turn that place into floor. Then it will choose a random direction, jump over the nearest mapgrid in that direction, and check the next mapgrid for solid stone. If there is solid stone, mazewalk will move that direction, changing that place and the intervening mapgrid to floor. Normally the generated maze will not have any loops. For example MAP TTTTTTT T T T T TTTTTTT T T T T TTTTTTT ENDMAP Pointing mazewalk at that will create a small maze of trees, but note that unless the map (at the place where it's put into the level) is surrounded by something else than solid stone, mazewalk will get out of that MAP. Substituting floor characters for some of the trees "in the maze" will make loops in the maze, which are not otherwise possible. Substituting floor characters for some of the trees at the edges of the map will make maze entrances and exits at those places. If the total area NOT covered by all maze-parts in the level is greater than 1/10 of the total area of the level, then the mazes in the level will get stocked with maze-specific stuff, such as minotaurs, traps and items, proportionally to the amount of space not covered by MAPs. Note that mazewalk will only work if the solid stone mapgrids in the level (where the MAP was put down) are on odd-numbered squares, both horizontally and vertically. You don't have to worry about this unless your MAP is 21 rows high or 76 columns wide, in which case you'll have to either make the MAP smaller, or move the places where the solid stone squares are. Also note that MAZEWALK will fail in certain types of MAP-parts if you also use WALLIFY, as that command is applied before MAZEWALKs. Example: MAZEWALK:(00,06),west WALLIFY WALLIFY Turns walls completely surrounded by other walls into solid stone ' '. LADDER LADDER:place, updown Places a ladder up or down at coordinate. See also STAIRS. *place is either a coordinate, a RANDOM_PLACES place, or random *updown is either up or down, denoting the direction of the stairs. Example: LADDER:(11,05),down GOLD GOLD:place, amount Places amount of gold in place. *place is either a coordinate, a RANDOM_PLACES place, or random *amount is any positive integer number. Example: GOLD:(5,5),12345 ROOM-type levels Room-type levels begin with LEVEL, followed by optional FLAGS, optional INIT_MAP, 0 or more MESSAGEs, followed by optional random register initializers (RANDOM_MONSTERS and RANDOM_OBJECT), followed by 0 or more ROOM and SUBROOM definitions (and the contents for those rooms), followed by RANDOM_CORRIDORS. That is: *LEVEL *FLAGS, optional *INIT_MAP, optional *MESSAGE, 0 or more *RANDOM_MONSTERS, optional *RANDOM_OBJECTS, optional **ROOM, 0 or more **contents for the room (monsters, objects, traps, etc.) **SUBROOM, 0 or more ***contents for the subroom (monsters, objects, traps, etc.) *RANDOM_CORRIDORS It's not possible to define arbitrarily shaped rooms with this type of level. LEVEL LEVEL: "name" "name" is the unique file name for this level. Can be up to 8 chars long. This file name is defined by the way this level is defined in dungeon.def. Example: LEVEL: "oracle" RANDOM_CORRIDORS RANDOM_CORRIDORS Creates random corridors between the rooms in the level, so that all rooms are accessible. ROOM ROOM: "type", lighted, pos, align, size Creates a room. The room will be placed on a position defined both by pos and align. pos defines the rough position (in a 5-by-5 grid on the screen), and align defines the room position within that. NOTE: Creation of a randomly located room may fail, especially if there's little free space to fit it on the level. Contents of such a room won't be created either. *"type" is one of the room types. *lighted is one of lit, unlit or random. *pos is either random or (xpos, ypos), where both xpos and ypos are between 0 and 5. This is an approximate coordinate on the screen. *align is either random or (xalign, yalign) and is the room alignment within the pos. **xalign is one of left, half-left, center, half-right, right or random **yalign is one of top, center, bottom or random. *size is either random or (width, height). You can also give one additional parameter, which can either be true or false. This tells whether the room will get stocked by objects and monsters it would normally get (such as shopkeepers and items for sale for shops). Example: ROOM: "ordinary", random, random, random, random ROOM: "ordinary", lit, (3,3), (center,center), (11,9) SUBROOM SUBROOM: "type", lighted, pos, size, "parent" Creates a room inside previously defined ROOM. *"type" is one of the room types. *lighted is one of lit, unlit or random. *pos is either random or (xpos, ypos), where xpos and ypos define the absolute position of this subroom inside the parent room. (0,0) is the upper left corner of the parent. *size is either random or (width, height). *"parent" is the name of the parent room, as defined with NAME. You can also give one additional parameter, which can either be true or false. This tells whether the room will get stocked by objects and monsters it would normally get (such as shopkeepers and items for sale for shops). Example: SUBROOM:"shop",lit,(10,10),(3,3),"town" SUBROOM:"ordinary",random,(19,2),(2,2),"town" NAME NAME: "string" Names the previously defined ROOM or SUBROOM. Subrooms need to know the name of their parent room, this has no other meaning. Example: NAME: "town" CHANCE CHANCE: int Assigns a creation chance to the previously defined ROOM or SUBROOM. The room walls and doors will get created no matter what, this just tells whether the room contents will be created. int should be in the 0-100 range. Only non-ordinary rooms can have this. Example: CHANCE: 90 Room DOOR DOOR: secret, state, wall, pos Creates a door with certain state on the previously defined ROOM or SUBROOM. Note that Room DOOR format is different from MAZE-level DOOR. *secret can be true, false or random *state is one of the following: nodoor, locked, closed, open or random *wall is one of the following: north, east, south or west and tells on what wall of the room the door will be created. *pos is either random or a positive integer, and tells how far from top or left the door will be. Example: DOOR: false, closed, south, random Common syntax The following commands are common to both MAZE and ROOM-type levels. For the MAZE-levels, the coordinates used are the previously defined MAP, for ROOM-levels, it's either the previously defined ROOM or SUBROOM. ALTAR ALTAR:place,align,type Places an altar on the previously defined map or ROOM or SUBROOM. *place is either a coordinate, a RANDOM_PLACES place, or random *align is either noalign, law, neutral, chaos, coaligned, noncoaligned, random or an alignment register alignN, where N can be either 0,1 or 2. *type is one of sanctum, shrine, altar or random Example: ALTAR:(50,14),chaos,altar ALTAR:place0,noalign,altar ALTAR:(07,09),align0,sanctum CONTAINER This defines a container that you can put items in. It accepts exactly the same parameters as OBJECT. Normal content generation for this object is suppressed. Example: CONTAINER:'(',"chest",(5,5) OBJECT:'/',"wishing",contained ENGRAVING ENGRAVING:place, type, "text" Creates an engraving on the floor. *place is either a coordinate, a RANDOM_PLACES place, or random *type is one of dust, engrave, burn, mark or random. *"text" is the text to engrave on the floor. Example: ENGRAVING:(12,03), engrave, "You are now entering the Gnome King's wine cellar." FOUNTAIN FOUNTAIN:place Places a fountain on the map. *place is either a coordinate, a RANDOM_PLACES place, or random Example: FOUNTAIN:(10,08) MONSTER MONSTER:'X',"monst",place *'X' is the monster class symbol, or random, or a RANDOM_MONSTERS index *"monst" is the specific monster, or random *place is either a coordinate, a RANDOM_PLACES place, or random Other things you can add to the monster definition: *hostile or peaceful *asleep or awake *For mimics and other shapechangers you can also add the following: **m_feature "dungeon_feature" to force the mimic to be a dungeon feature. **m_object "object_name" to force the mimic to be an object. object_name is the name of an object as they are in objects.c **m_monster "monster_name" to force the shapechanger to be a certain monster. *"Name" to name the monster. Optionally, you can put NN% right after MONSTER to make the monster generation optional. NN is a percentage chance of the monster being generated when the level is created. Examples: MONSTER:'v',"dust vortex",(42,05) MONSTER:'E',"earth elemental",(39,06),peaceful MONSTER:'&',"Pestilence",place0,hostile MONSTER:random,random,random MONSTER:random,random,(01,01), asleep MONSTER:monster0,random,(27,05) MONSTER:'m',"giant mimic",place1,m_feature "fountain" MONSTER:'m',random,place0, m_object "luckstone" MONSTER:'@',"rogue",(35,06),peaceful,"Pug" MONSTER50%:'P', "green slime", random OBJECT OBJECT:'X',"name",place Each map-part can contain any number of object definitions. *'X': a character denoting one of the object classes. *"name": either an object name as listed in objects.c, or random *place: either a coordinate, a RANDOM_PLACES place, or random, or contained. If contained, then this object will be placed in the previously defined CONTAINER. Optional stuff you can add to the object definition: *cursestate, "monster_id", spe *cursestate, spe *"monster_id", spe Where *cursestate is one of blessed, uncursed, cursed or random. *"monster_id" is a monster type, as defined in monst.c *spe is an integer, and defines different things depending on what kind of object is generated: **enchantment for armor and weapons **charges for wands, rings, magic markers and everything else that has charges. **historic and gender bit for statues. 1 is historic, 2 is male, 4 is female. Adding the values together is possible, so you can create eg. historic, male statue with value 3 and historic, female with 5. Leaving the gender specification out will either result in a random gender, or if the monster is always of certain gender, then the statue will be that gender too. (eg. nymphs) **tins: 1 means spinach, -1 is home-made. **containers: 1 means the box contains Shroedinger's cat. **oil lamps and candles: 0 means the lamp is out of oil. **Candelabrum: how many candles are attached to it. **scroll of mail: 1 means it was not delivered to current player. **eggs: 1 means hero laid it. **chests: 2 means it's a royal coffer in a throne room. After these you can also add a quoted string, which would become the object's name. Optionally, you can put NN% right after OBJECT to make the object generation optional. NN is a percentage chance of the object being generated when the level is created. Examples: OBJECT:'%', "food ration", random OBJECT:'*', random, (10,10) OBJECT:'?', "genocide", place0 OBJECT10%:'"', "amulet of life saving", random OBJECT:'%', "corpse", random, "archeologist", 0 OBJECT50%:')', "scimitar", contained, blessed, +2 OBJECT:'`', "statue", (0,0), "forest centaur", 1 OBJECT:'(', "crystal ball", (17,08), blessed, 5, "The Orb of Fate" STAIR STAIR:place, updown Places a stair up or down at coordinate. See also STAIR-region and LADDER. *place is either a coordinate, a RANDOM_PLACES place, or random *updown is either up or down, denoting the direction of the stairs. Example: STAIR:(70,08), up STAIR:random, down STAIR:place3, up TRAP TRAP:"name",place *"name" is the trap's name, or random *place is either a coordinate, a RANDOM_PLACES place, or random Optionally, you can put NN% right after TRAP to make the trap generation optional. NN is a percentage chance of the trap being generated when the level is created. Examples: TRAP:"hole",(12,10) TRAP:"anti magic",random TRAP:random,random TRAP25%:"polymorph",random Map characters Trap names "anti magic", "arrow", "bear", "board", "dart", "falling rock", "fire", "hole", "land mine", "level teleport", "magic portal", "magic", "pit", "polymorph", "rolling boulder", "rust", "sleep gas", "spiked pit", "statue", "teleport", "trap door", "web" Room types "ordinary", "throne", "swamp", "vault", "beehive", "morgue", "barracks", "zoo", "delphi", "temple", "anthole", "cocknest", "leprehall", "shop", "armor shop", "scroll shop", "potion shop", "weapon shop", "food shop", "ring shop", "wand shop", "tool shop", "book shop", "candle shop" Category:Annotations